home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / libs / sphigs / sph_dos.lha / dos / sphsrc / sph_edit.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-11-26  |  8.8 KB  |  375 lines

  1. #include "HEADERS.h"
  2. #include "sphigslocal.h"
  3. #include <string.h> 
  4.  
  5. static element *element_ptr;
  6. static int      element_ptr_index;
  7.  
  8. static substruct_bitstring possible_no_longer_child = NULL;
  9.  
  10. int ID_of_open_struct;
  11. structure *OPENSTRUCT;
  12.  
  13.  
  14.  
  15. element *SPH__currentElementDirectAccess ()
  16. {
  17.    return element_ptr;
  18. }
  19.  
  20.  
  21.  
  22.  
  23. /** SPH_cleanup_and_kill_element
  24. Frees up any malloc'd areas associated with an element.
  25. **/
  26.  
  27. static void SPH_cleanup_and_kill_element (element *elptr)
  28. {
  29.    switch (elptr->type) {
  30.       
  31.     case ELTYP__POLYHEDRON:
  32.       SPH__freePolyhedron (elptr->data.poly);
  33.       break;
  34.  
  35.     case ELTYP__POLYMARKER:
  36.     case ELTYP__POLYLINE:
  37.     case ELTYP__FILL_AREA:
  38.       free (elptr->data.points);
  39.       break;
  40.  
  41.     case ELTYP__EXECUTE_STRUCTURE:
  42.       SPH__structureTable[elptr->data.value].refcount--;
  43.       SetBit (possible_no_longer_child, elptr->data.value);
  44.       break;
  45.       
  46.    }
  47.  
  48.    free (elptr);
  49. }
  50.  
  51.  
  52.  
  53.  
  54. /** SPH_inquireElptr
  55. **/
  56. int
  57. SPH_inquireElementPointer (void)
  58. {
  59.    SPH_check_system_state;
  60.    SPH_check_open_structure;
  61.    return element_ptr_index;
  62. }
  63.  
  64.  
  65. /** SPH_init_structure_table
  66. All structures exist initially; they're simply empty.
  67. **/
  68. void
  69. SPH__init_structure_table (void)
  70. {
  71.    register i;
  72.  
  73.    bzero (SPH__structureTable, sizeof(structure)*(MAX_STRUCTURE_ID+1));
  74.    for (i=0; i<=MAX_STRUCTURE_ID; i++) {
  75.       ClearBitstring (&(SPH__structureTable[i].child_list));
  76.    }
  77. }
  78.  
  79.  
  80.  
  81.  
  82. /** INTERNAL USE ONLY: SPH__insertElement
  83. Inserts given element in the currently open structure so that it
  84.    follows the currently active element.
  85. Because internal-use only, ASSUMES THERE IS AN OPEN STRUCTURE.
  86. **/
  87.  
  88. void
  89. SPH__insertElement (element *baby)
  90. {
  91.    if (element_ptr == NULL) {
  92.       /* BEING INSERTED AT VERY BEGINNING OF STRUCTURE */
  93.       baby->next = OPENSTRUCT->first_element;
  94.       OPENSTRUCT->first_element = baby;
  95.       baby->previous = NULL;
  96.    }
  97.    else {
  98.       /* BEING INSERTED AFTER AT LEAST ONE EXTANT ELEMENT */
  99.       baby->next = element_ptr->next;
  100.       element_ptr->next = baby;
  101.       baby->previous = element_ptr;
  102.    }
  103.  
  104.    OPENSTRUCT->element_count++;
  105.    if (baby->next == NULL)
  106.       OPENSTRUCT->last_element = baby;
  107.    else
  108.       baby->next->previous = baby;
  109.    element_ptr = baby;
  110.    element_ptr_index++;
  111. }
  112.  
  113.  
  114. /** SPH_openStructure
  115. **/
  116. void
  117. SPH_openStructure (structID)
  118. int structID;
  119. {
  120.    SPH_check_system_state;
  121.    SPH_check_no_open_structure;
  122.    SPH_check_structure_id;
  123.  
  124.    ID_of_open_struct = structID;
  125.    OPENSTRUCT = &(SPH__structureTable[structID]);
  126.    element_ptr_index = OPENSTRUCT->element_count;
  127.    element_ptr = OPENSTRUCT->last_element;
  128.    SPH__structureCurrentlyOpen = TRUE;
  129.  
  130.    if (NULL == possible_no_longer_child)
  131.       possible_no_longer_child = (unsigned char*) malloc (BYTES_PER_BITSTRING);
  132.  
  133.    ClearBitstring (&possible_no_longer_child);
  134. }
  135.    
  136.  
  137. static substruct_bitstring BB = NULL;
  138.  
  139.  
  140. /** SPH_closeStructure
  141. **/
  142. void
  143. SPH_closeStructure ()
  144. {
  145.    SPH_check_system_state;
  146.    SPH_check_open_structure;
  147.  
  148.    /* IF AN INVOCATION WAS DESTROYED BY THE EDITING.... */
  149.    if ( ! BitstringIsClear(possible_no_longer_child)) {
  150.       register element *elptr;
  151.  
  152.  
  153.       /* RECALC CHILD_LIST */
  154.       ClearBitstring (&(OPENSTRUCT->child_list));
  155.       elptr = OPENSTRUCT->first_element;
  156.       while (elptr) {
  157.           if (elptr->type == ELTYP__EXECUTE_STRUCTURE)
  158.              SetBit (OPENSTRUCT->child_list, elptr->data.value);
  159.          elptr = elptr->next;
  160.       }
  161.       
  162.       /* TEST FOR OBSOLESCENCE OF DEPENDENCIES. */
  163.       ClearBitstring (&BB);  /* forces a malloc the 1st time around */
  164.       AndBitstrings (BB, possible_no_longer_child, OPENSTRUCT->child_list);
  165.       /* NOW: BB is a list of all structures that are definitely
  166.        *   children AND that were suspected of having been lost by
  167.        *   a deletion of an invocation.
  168.        * IF BB is equal to the list of all structures suspected of
  169.        *   having been lost, then it must be true that NO
  170.        *   children were lost due to editing in this session.
  171.        * IF BB is NOT equal to...,  then it must be true that
  172.        *   at least one child was lost, and some views' descendent-lists
  173.        *   may now be obsolete!
  174.        */
  175.       if ( ! BitstringsAreEqual (BB, possible_no_longer_child)) 
  176.          /* All views that own S now have obsolete descendent lists! */
  177.          VIEWOPT__afterChildLoss (ID_of_open_struct);
  178.    }
  179.  
  180.    SPH__structureCurrentlyOpen = FALSE;
  181.    SPH__refresh_structure_close (ID_of_open_struct);
  182. }
  183.  
  184.  
  185.  
  186. /** SPH_setElptr
  187. Special case: 0 means set elptr to even before the very first element.
  188.               1 means set elptr to very first element.
  189. **/
  190. void
  191. SPH_setElementPointer (index)
  192. int index;
  193. {
  194.    register i;
  195.  
  196.    SPH_check_system_state;
  197.    SPH_check_open_structure;
  198.  
  199.    if (index == 0)
  200.       element_ptr = NULL;
  201.    else
  202.       if ((index > OPENSTRUCT->element_count) || (index < 0))
  203.      SPH__error (ERR_BAD_SET_ELPTR);
  204.       else {
  205.      element_ptr = OPENSTRUCT->first_element;
  206.      for (i=1; i<index; i++)
  207.         element_ptr = element_ptr->next;
  208.       }
  209.  
  210.    element_ptr_index = index;
  211. }
  212.       
  213.  
  214.  
  215. /** SPH_offsetElptr
  216. Its internal call to SPH_setElptr does the verification work on the index.
  217. **/
  218. void
  219. SPH_offsetElementPointer (delta)
  220. int delta;
  221. {
  222.    SPH_check_system_state;
  223.    SPH_check_open_structure;
  224.  
  225.    element_ptr_index += delta;
  226.    SPH_setElementPointer (element_ptr_index);
  227. }
  228.  
  229.  
  230. /** SPH_moveElptrToLabel
  231. Question: should I include the current element in the search?  Or does
  232. the search begin with the first element after the current one?
  233.  
  234. This version does NOT include the current element in the search.
  235. This version gives fatal error if label not found.
  236. **/
  237. void
  238. SPH_moveElementPointerToLabel (lab)
  239. int lab;
  240. {
  241.    SPH_check_system_state;
  242.    SPH_check_open_structure;
  243.  
  244.    while (1) {
  245.       /* ADVANCE ELEMENT POINTER */
  246.       element_ptr_index++;
  247.       if (element_ptr_index == 1)
  248.      element_ptr = OPENSTRUCT->first_element;
  249.       else
  250.      element_ptr = element_ptr->next;
  251.  
  252.       if ( ! element_ptr)
  253.      /* REACHED END: NOT FOUND: FATAL ERROR */
  254.      SPH__error (ERR_LABEL_NOT_FOUND);
  255.       
  256.       if (  (element_ptr->type == ELTYP__LABEL)
  257.      && (element_ptr->data.value == lab) )
  258.         /* FOUND */
  259.         break;
  260.    }
  261. }
  262.  
  263.  
  264.  
  265.  
  266. /** SPH_deleteEl
  267. Element pointer is left pointing to the element (if any) just before
  268.    the one to be killed.
  269. **/
  270. void
  271. SPH_deleteElement (void)
  272. {
  273.    element *el_to_die;
  274.  
  275.    SPH_check_system_state;
  276.    SPH_check_open_structure;
  277.    if (element_ptr == NULL)
  278.       SPH__error (ERR_NO_ELEMENT_TO_DELETE);
  279.  
  280.    /* FIRST, HANDLE ITS RELATIONSHIP TO ITS PREVIOUS ELEMENTS */
  281.    if (element_ptr->previous == NULL)
  282.       OPENSTRUCT->first_element = element_ptr->next;
  283.    else
  284.       element_ptr->previous->next = element_ptr->next;
  285.    /* THEN, HANDLE ITS RELATIONSHIP TO ITS NEXT ELEMENTS */
  286.    if (element_ptr->next == NULL)
  287.       OPENSTRUCT->last_element = element_ptr->previous;
  288.    else
  289.       element_ptr->next->previous = element_ptr->previous;
  290.  
  291.    /* UPDATE ELEMENT-COUNT AND ELEMENT-POINTER */
  292.    OPENSTRUCT->element_count--;
  293.    el_to_die = element_ptr;
  294.    element_ptr = el_to_die->previous;
  295.    element_ptr_index--;
  296.  
  297.  
  298.    SPH_cleanup_and_kill_element (el_to_die);
  299. }
  300.  
  301.  
  302.  
  303.  
  304.  
  305.  
  306. /** SPH_deleteElsInRange
  307. **/
  308. void
  309. SPH_deleteElementsInRange (first_index, second_index)
  310. int first_index, second_index;
  311. {
  312.    element *first_el_to_die, *last_el_to_die;
  313. #define number_to_be_killed    (second_index - first_index + 1)
  314.  
  315.    SPH_check_system_state;
  316.    SPH_check_open_structure;
  317.    
  318.    SPH_setElementPointer (first_index);
  319.    first_el_to_die = element_ptr;
  320.    SPH_setElementPointer (second_index);
  321.    last_el_to_die = element_ptr;
  322.  
  323.    SPH_check_elindex_range;
  324.  
  325.    /* FIRST, HANDLE ITS RELATIONSHIP TO ITS PREVIOUS ELEMENTS */
  326.    if (first_el_to_die->previous == NULL)
  327.       OPENSTRUCT->first_element = last_el_to_die->next;
  328.    else
  329.       first_el_to_die->previous->next = last_el_to_die->next;
  330.  
  331.    /* THEN, HANDLE ITS RELATIONSHIP TO ITS NEXT ELEMENTS */
  332.    if (last_el_to_die->next == NULL)
  333.       OPENSTRUCT->last_element = first_el_to_die->previous;
  334.    else
  335.       last_el_to_die->next->previous = first_el_to_die->previous;
  336.  
  337.    /* UPDATE ELEMENT-COUNT AND ELEMENT-POINTER */
  338.    OPENSTRUCT->element_count -= number_to_be_killed;
  339.    element_ptr = first_el_to_die->previous;
  340.    element_ptr_index = first_index - 1;
  341.  
  342.    /* KILL AND CLEANUP THE ELEMENTS */
  343.    do {
  344.       SPH_cleanup_and_kill_element (first_el_to_die);
  345.       if (first_el_to_die == last_el_to_die)
  346.      break;
  347.       else
  348.      first_el_to_die = first_el_to_die->next;
  349.    } while (1);
  350. }
  351.  
  352.  
  353.  
  354. /** SPH_deleteElsBetweenLabels
  355. **/
  356. void
  357. SPH_deleteElementsBetweenLabels (lab1, lab2)
  358. int lab1, lab2;
  359. {
  360.    int first_index, second_index;
  361.  
  362.    SPH_check_system_state;
  363.    SPH_check_open_structure;
  364.  
  365.    SPH_moveElementPointerToLabel (lab1);
  366.    first_index = element_ptr_index;
  367.    SPH_moveElementPointerToLabel (lab2);
  368.    second_index = element_ptr_index;
  369.    if (first_index == (second_index-1))
  370.       /* do nothing: nothing lies between the label elements */;
  371.    else
  372.       SPH_deleteElementsInRange (first_index+1, second_index-1);
  373. }
  374.  
  375.